package com.lawyer.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.lawyer.config.QiniuConfigBean;
import com.lawyer.config.WeiPayBean;
import com.lawyer.entity.Config;
import com.lawyer.entity.Coupon;
import com.lawyer.entity.Lawyer;
import com.lawyer.entity.MealConfiguration;
import com.lawyer.entity.MoneyFlows;
import com.lawyer.entity.OrderInfo;
import com.lawyer.entity.User;
import com.lawyer.entity.UserLawyers;
import com.lawyer.model.FocusLawyerReq;
import com.lawyer.model.FocusLawyerResponse;
import com.lawyer.model.Message;
import com.lawyer.model.MessageConstant;
import com.lawyer.model.UpdateUserReq;
import com.lawyer.model.WxMessage;
import com.lawyer.model.wx.Resource;
import com.lawyer.model.wx.WxPayResponse;
import com.lawyer.model.wx.WxPayResult;
import com.lawyer.qrode.QRCodeUtil;
import com.lawyer.repository.ConfigRepository;
import com.lawyer.repository.CouponRepository;
import com.lawyer.repository.LawyerRepository;
import com.lawyer.repository.MealConfigurationRepository;
import com.lawyer.repository.MoneyFlowsRepository;
import com.lawyer.repository.OrderInfoRepository;
import com.lawyer.repository.UserLawyerRepository;
import com.lawyer.repository.UserMicroInfoRepository;
import com.lawyer.repository.UserRepository;
import com.lawyer.service.FileUpLoadService;
import com.lawyer.service.OrderInfoService;
import com.lawyer.uitls.AesUtil;
import com.lawyer.uitls.BeanUtils;
import com.lawyer.uitls.CertificatesUitl;
import com.lawyer.uitls.DateUtils;

@RestController
@RequestMapping(value = "/user")
@Api(tags = "用户相关")
@SuppressWarnings("all")
public class UserController {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private UserRepository userRepository;
	@Autowired
	private FileUpLoadService fileUpLoadService;

	@Autowired
	private EntityManager entityManager;
	@Autowired
	private LawyerRepository lawyerRepository;

	@Autowired
	private UserMicroInfoRepository userMicroInfoRepository;

	@Autowired
	private MoneyFlowsRepository moneyFlowsRepository;

	@Autowired
	private UserLawyerRepository userLawyerRepository;

	@Autowired
	private CouponRepository couponRepository;
	@Autowired
	private MealConfigurationRepository mealConfigurationRepository;

	@Autowired
	QiniuConfigBean qiniuConfigBean;

	@Autowired
	private OrderInfoService orderInfoService;

	@Autowired
	private OrderInfoRepository orderInfoRepository;

	@Autowired
	private ConfigRepository configRepository;

	@Autowired
	private WeiPayBean weiPayBean;

	@ApiOperation(httpMethod = "GET", value = "用户基础信息", notes = "用户基础信息")
	@RequestMapping(value = "/userInfo", method = RequestMethod.GET)
	public HttpEntity<?> userInfo(@RequestParam String userId) {
		Message msg = new Message();
		try {
			if (userId != null) {
				User user = userRepository.findOne(userId);
				user.setPassword(null);
				msg.setData(user);
			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("没有找到用户");
			}
		} catch (Exception e) {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "POST", value = "修改个人信息", notes = "修改个人信息")
	@RequestMapping(value = "/upadte", method = RequestMethod.POST)
	public HttpEntity<?> upadte(@RequestBody UpdateUserReq updateUserReq) {
		Message msg = new Message();
		try {
			User user = userRepository.findOne(updateUserReq.getUserId());
			if (user != null) {
				BeanUtils.copyPropertiesIgnoreNullValue(updateUserReq, user,"dedication");
				userRepository.save(user);
			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("用户不存在");
			}
		} catch (Exception e) {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}
		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "GET", value = "我的钱包", notes = "我的钱包")
	@ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "integer", paramType = "query", value = "第几页"),
			@ApiImplicitParam(name = "size", dataType = "integer", paramType = "query", value = "分页条数") })
	@RequestMapping(value = "/myWallet", method = RequestMethod.GET)
	public HttpEntity<?> myWallet(@PageableDefault(page = 0, sort = { "createdDate" }, direction = Sort.Direction.DESC) Pageable pageable, @RequestParam String userId) {
		Message msg = new Message();
		try {
			if (userId != null) {

				User user = userRepository.findOne(userId);
				if (user != null) {
					Map<String, Object> resultMap = ListOrderedMap.decorate(new HashMap<String, Object>());

					resultMap.put("balance", user.getBalance());

					Page<MoneyFlows> page = moneyFlowsRepository.findByUserId(userId, pageable);
					resultMap.put("balanceInfoPage", page);

					msg.setData(resultMap);
				} else {
					msg.setCode(MessageConstant.FAILED_CODE);
					msg.setMessage("没有找到用户");
				}

			}

		} catch (Exception e) {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "GET", value = "我的优惠券", notes = "isUsed:优惠券是否被使用(true=已使用,false=未使用)")
	@RequestMapping(value = "/myCoupon", method = RequestMethod.GET)
	public HttpEntity<?> myCoupon(@RequestParam(required = true) String userId) {
		Message msg = new Message();
		try {
			if (StringUtils.isNotEmpty(userId)) {
				List<Coupon> list = couponRepository.findByUserId(userId);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

				Iterator<Coupon> iterator = list.iterator();
				while (iterator.hasNext()) {
					Coupon coupon = iterator.next();
					String endDate = sdf.format(coupon.getEndDate());
					if (DateUtils.checktime(endDate)) {
						// 已过期
						coupon.setIsExpire(true);
						couponRepository.save(coupon);
					}

				}

				msg.setData(list);
			}

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}
	
	
	@ApiOperation(httpMethod = "PUT", value = "自定义充值余额", notes = "自定义充值余额")
	@RequestMapping(value = "/prepaidCustom", method = RequestMethod.PUT)
	public HttpEntity<?> prepaidCustom(Double price, String userId) {
		Message msg = new Message();
		try {

			User user = userRepository.findOne(userId);
			if (user != null) {
				Integer total = new BigDecimal(price * 100).intValue();
				String orderId = DateUtils.randomNumber();

				OrderInfo info = new OrderInfo();
				info.setId(orderId);
				info.setUserId(userId);
				info.setTotal(total);
				info.setIsPay(false);
				info.setMealId(0);
				info.setUrlType(weiPayBean.getJsapiUrl());
				String prepayId = orderInfoService.wxCreateOrder(info);
				if (StringUtils.isNotEmpty(prepayId)) {
					info.setPrepayId(prepayId);
					orderInfoRepository.save(info);
					msg.setData(info);
				} else {
					msg.setCode(MessageConstant.FAILED_CODE);
					msg.setMessage("操作失败");
				}

			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("账号不存在");
			}
		

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "PUT", value = "充值余额", notes = "充值余额")
	@RequestMapping(value = "/prepaid", method = RequestMethod.PUT)
	public HttpEntity<?> prepaid(Integer mealId, String userId) {
		Message msg = new Message();
		try {

			MealConfiguration meal = mealConfigurationRepository.findOne(mealId);
			if (meal != null) {
				User user = userRepository.findOne(userId);
				if (user != null) {
					Integer total = new BigDecimal(meal.getPrice() * 100).intValue();
					String orderId = DateUtils.randomNumber();

					OrderInfo info = new OrderInfo();
					info.setId(orderId);
					info.setUserId(userId);
					info.setTotal(total);
					info.setIsPay(false);
					info.setMealId(mealId);
					info.setUrlType(weiPayBean.getJsapiUrl());
					String prepayId = orderInfoService.wxCreateOrder(info);
					if (StringUtils.isNotEmpty(prepayId)) {
						info.setPrepayId(prepayId);
						orderInfoRepository.save(info);
						msg.setData(info);
					} else {
						msg.setCode(MessageConstant.FAILED_CODE);
						msg.setMessage("操作失败");
					}

				} else {
					msg.setCode(MessageConstant.FAILED_CODE);
					msg.setMessage("账号不存在");
				}
			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("所选套餐不存在");
			}

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "POST", value = "充值成功后回调", notes = "充值成功后回调")
	@RequestMapping(value = "/wxPayCallBlack", method = RequestMethod.POST)
	public HttpEntity<?> wxPayCallBlack(HttpServletRequest request, HttpServletResponse response) {
		WxMessage msg = new WxMessage();
		try {
			logger.info("收到回调......");
			BufferedReader bufferedReader = null;
			StringBuilder sb = null;
			try {
				bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
				sb = new StringBuilder();
				String line = bufferedReader.readLine();
				while (line != null) {
					sb.append(line);
					line = bufferedReader.readLine();
					if (line != null) {
						sb.append("\n");
					}
				}
			} finally {
				bufferedReader.close();
			}
			logger.info("支付成功后收到回调数据：" + sb.toString());
			WxPayResponse wxPay = JSON.parseObject(sb.toString(), WxPayResponse.class);
			// 解密
			AesUtil aesUtil = new AesUtil(weiPayBean.getApiV3Key().getBytes());
			Resource resource = wxPay.getResource();
			String orderData = aesUtil.decryptToString(resource.getAssociated_data().getBytes(), resource.getNonce().getBytes(), resource.getCiphertext());

			WxPayResult result = JSON.parseObject(orderData, WxPayResult.class);

			if ("SUCCESS".equals(result.getTrade_state())) {
				Double amount = 0D;
				int total = result.getAmount().getTotal();// 充值的金额
				if (total >= 100) {
					amount = Double.valueOf(total / 100);
				} else {
					if (total <= 9) {
						String totalStr = "0.0" + total;
						amount = Double.valueOf(totalStr);
					} else {
						String totalStr = "0." + total;
						amount = Double.valueOf(totalStr);
					}
				}

				// 更新订单信息
				OrderInfo info = orderInfoRepository.findOne(result.getOut_trade_no());
				info.setIsPay(true);
				// 更新用户余额
				User user = userRepository.findOne(result.getPayer().getOpenid());

				if (user != null) {
					user.setBalance(user.getBalance() + amount);
					userRepository.save(user);

					// 保存变更记录
					MoneyFlows flow = new MoneyFlows();
					flow.setTypeFlow(1);
					flow.setUserId(user.getId());
					flow.setUserName(user.getNickName());
					flow.setPhone(user.getPhone());
					flow.setUserType(user.getUserType());
					flow.setChangeMoney(amount);
					flow.setDescription("充值");
					moneyFlowsRepository.save(flow);

				} else {
					msg.setCode(MessageConstant.FAILED_CODE);
					msg.setMessage("账号不存在");
				}

				logger.info("解析得到的数据：" + orderData);
			}

		} catch (Exception e) {

		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@RequestMapping(value = "/myFocus", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "我关注律师", notes = "我关注律师")
	@ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "integer", paramType = "query", value = "第几页"),
			@ApiImplicitParam(name = "size", dataType = "integer", paramType = "query", value = "分页条数") })
	public HttpEntity<?> myFocus(@PageableDefault(page = 0, sort = { "createdDate" }, direction = Sort.Direction.DESC) Pageable pageable,
			@RequestParam(required = true) String userId) {

		Message msg = new Message();
		try {
			FocusLawyerResponse respone = new FocusLawyerResponse();
			respone.setUserId(userId);
			List<Lawyer> lawyers = new ArrayList<Lawyer>();

			Page<UserLawyers> myLawyers = userLawyerRepository.findByUserId(userId, pageable);
			List<UserLawyers> list = myLawyers.getContent();

			for (UserLawyers userLawyers : list) {
				Lawyer lawyer = lawyerRepository.findOne(userLawyers.getLawyerId());
				Config config = configRepository.findByName("ConsultingFee");// 律师咨询费
				if(lawyer!=null){
					lawyer.setConsultPrice(Double.valueOf(config.getValue()));
					lawyer.setPhone("17138306056");
					lawyers.add(lawyer);
				}
			}

			respone.setLawyers(lawyers);

			msg.setData(respone);
		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "POST", value = "添加关注律师", notes = "添加关注律师")
	@RequestMapping(value = "/focusLawyer", method = RequestMethod.POST)
	public HttpEntity<?> focusLawyer(@RequestBody FocusLawyerReq req) {
		Message msg = new Message();
		try {
			Lawyer lawyer = lawyerRepository.findOne(req.getLawyerId());
			User user = userRepository.findOne(req.getUserId());

			if (lawyer != null && user != null) {
				String idStr = req.getUserId() + req.getLawyerId();
				String id = UUID.nameUUIDFromBytes(idStr.getBytes()).toString();

				UserLawyers rel = new UserLawyers();
				rel.setId(id);
				rel.setLawyerId(req.getLawyerId());
				rel.setUserId(req.getUserId());
				userLawyerRepository.save(rel);
			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("没找到相关麦律师");
			}

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "POST", value = "取消关注律师", notes = "取消关注律师")
	@RequestMapping(value = "/unFocusLawyer", method = RequestMethod.POST)
	public HttpEntity<?> unFocusLawyer(@RequestBody FocusLawyerReq req) {
		Message msg = new Message();
		try {
			Lawyer lawyer = lawyerRepository.findOne(req.getLawyerId());
			User user = userRepository.findOne(req.getUserId());

			if (lawyer != null && user != null) {
				String idStr = req.getUserId() + req.getLawyerId() + "";
				String id = UUID.nameUUIDFromBytes(idStr.getBytes()).toString();
				userLawyerRepository.delete(id);
			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("没找到相关麦律师");
			}

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "GET", value = "我的二维码(代理推广码)", notes = "我的二维码(代理推广码)")
	@RequestMapping(value = "/myQrCode", method = RequestMethod.GET)
	public HttpEntity<?> myQrCode(@RequestParam(required = true, name = "userId") String userId) {
		Message msg = new Message();
		String qrCode = null;
		try {
			User user = userRepository.findOne(userId);

			if (StringUtils.isEmpty(user.getQrCode())) {
				String url = qiniuConfigBean.getServiceUrl() + "/regimental/group?type=agent&userId=" + userId;
				InputStream input = QRCodeUtil.getImageStream(user.getHeaderIco());
				InputStream qrCodeInput = QRCodeUtil.encode(url, input, true);

				Message result = fileUpLoadService.Upload(qrCodeInput);
				if (MessageConstant.SUCCESS_CODE.equals(result.getCode())) {
					qrCode = result.getData().toString();
					user.setQrCode(qrCode);
					userRepository.save(user);
				}
			} else {
				qrCode = user.getQrCode();
			}
			// --------------推广码-------------
			// if (StringUtils.isEmpty(user.getQrCode())) {
			// Integer count = userRepository.queryMaxCode();
			// qrCode = count + "";
			// user.setQrCode(qrCode);
			// userRepository.save(user);
			// } else {
			// qrCode = user.getQrCode();
			// }

			msg.setData(qrCode);

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@RequestMapping(value = "/getPayParameter", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "获取支付参数", notes = "获取支付参数")
	public HttpEntity<?> getPayParameter(String prepayId) {
		Message msg = new Message();
		try {

			Map<String, String> map = new HashMap<String, String>();
			long timeStamp = System.currentTimeMillis() / 1000;
			map.put("appId", weiPayBean.getAppId());
			map.put("timeStamp", String.valueOf(timeStamp));
			map.put("nonceStr", BeanUtils.getRandomString(32));
			map.put("package", "prepay_id=" + prepayId);

			Map result = CertificatesUitl.getToken(map);
			msg.setData(result);
		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}
	
	
	@ApiOperation(httpMethod = "GET", value = "我的绑定的代理", notes = "我的绑定的代理")
	@RequestMapping(value = "/myAgent", method = RequestMethod.GET)
	public HttpEntity<?> myAgent(String userId) {
		Message msg = new Message();
		try {
			User user = userRepository.findOne(userId);
			if (user.getAgentId() != null) {
				User agent = userRepository.findOne(user.getAgentId());
				msg.setData(agent);
			}else{
				msg.setData("没有绑定代理");
			}
		

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

}
